
#include "msg.h"
#include "shm.h"

struct msgin
{
    char name[32]; // 设备名称：tem、ill、led、beep
    int type;      // 1: int  2:float
    int val_int;
    float val_flt;
};

void *get_info(void *arg);
void *set_op(void *arg);

int main(int argc, const char *argv[])
{
    modbus_t *ctx;
    pthread_t t1, t2;
    // 创建modbus实例
    ctx = modbus_new_tcp(argv[1], 502);
    if (ctx == NULL)
    {
        printf("new modbus err");
        return -1;
    }
    // 设置从机ID
    modbus_set_slave(ctx, 1);
    // 建立连接
    if (modbus_connect(ctx) < 0)
    {
        printf("connect err");
        modbus_free(ctx);
        return -1;
    }
    printf("connect success\n");

    pthread_create(&t1, NULL, get_info, ctx);
    pthread_create(&t2, NULL, set_op, ctx);

    pthread_join(t1, NULL); // 阻塞
    pthread_join(t2, NULL);

    // 关闭套接字
    modbus_close(ctx);
    // 释放空间
    modbus_free(ctx);

    return 0;
}
void *get_info(void *arg) // 03功能码
{
    char *p = NULL;
    shm_init(&p);
    struct msgin m[3];
    uint16_t data[5] = {0};
    modbus_t *ctx = (modbus_t *)arg;
    while (1)
    {
        // 读保持寄存器的数据
        modbus_read_registers(ctx, 0, 5, data);
        strcpy(m[0].name, "温度");
        m[0].type = 2;
        m[0].val_flt = modbus_get_float_dcba(data);

        strcpy(m[1].name, "湿度");
        m[1].type = 2;
        m[1].val_flt = modbus_get_float_dcba(data + 2);

        strcpy(m[2].name, "光照强度");
        m[2].type = 1;
        m[2].val_int = *(data + 4);
        sprintf(p, "%s:%.2f℃ %s:%.2f%%RH %s:%dlx\n", m[0].name, m[0].val_flt, m[1].name, m[1].val_flt, m[2].name, m[2].val_int);
        // 将数据打印
        sleep(3);
    }
}
void *set_op(void *arg) // 01功能码
{

    struct msg rcvbuf;
    modbus_t *ctx = (modbus_t *)arg;
    int msgid = msg_init();
    size_t s = sizeof(rcvbuf) - sizeof(long);

    while (1)
    {
        printf("+++++\n");

        msgrcv(msgid, &rcvbuf, s, 0, 0);

        if (rcvbuf.mtype == 10 && strcmp(rcvbuf.mtext, "led") == 0)
            modbus_write_bit(ctx, 0, 0);

        else if (rcvbuf.mtype == 1 && strcmp(rcvbuf.mtext, "led") == 0)
            modbus_write_bit(ctx, 0, 1);

        else if (rcvbuf.mtype == 10 && strcmp(rcvbuf.mtext, "beep") == 0)
            modbus_write_bit(ctx, 1, 0);

        else if (rcvbuf.mtype == 1 && strcmp(rcvbuf.mtext, "beep") == 0)
            modbus_write_bit(ctx, 1, 1);
    }
}